package chelydra.sharelydra.client.friend;

import java.util.Date;
import java.util.Hashtable;
import java.util.Map;

/**
 *
 * @author Pierre-Élie Fauché
 */
public class Notification {

	// THESE MUST BE IDENTICAL WITH THE EJB
	public static final int FRIENDSHIP_PROPOSAL = 1;
	public static final int FRIENDSHIP_ACCEPTED = 3;
	public static final int FRIENDSHIP_DECLINED = 5;
	public static final int FRIENDSHIP_REMOVED = 11;
	public static final int NOTIFY_FILE = 21;

	public static final int SENT_FRIENDSHIP_PROPOSAL = 901;
	public static final int SENT_FRIENDSHIP_ACCEPTED = 903;
	public static final int SENT_FRIENDSHIP_DECLINED = 905;
	public static final int SENT_FRIENDSHIP_REMOVED = 9011;
	public static final int SENT_NOTIFY_FILE_GROUP = 9021;
	public static final int SENT_NOTIFY_FILE_FRIEND = 9022;

    public static final int FILE_DOWNLOADING_STARTED = 101;
    public static final int FILE_DOWNLOAD_FINISHED = 102;
    public static final int FILE_DOWNLOAD_ERROR = 103;

    public static final int LIST_FILE_DOWNLOADED = 201;
    public static final int LIST_FILE_SENT = 202;
    
	private Date createdTime;
	private Integer type;
	private String content;
	private String senderLogin;
	private String senderNickname;
	private String receiverLogin;

	public Notification(Date createdTime, Integer type, String content, String senderLogin, String senderNickname, String receiverLogin) {
		this.createdTime = createdTime;
		this.type = type;
		this.content = content;
		this.senderLogin = senderLogin;
		this.senderNickname = senderNickname;
		this.receiverLogin = receiverLogin;
	}

    public Notification(Integer type, String otherUser, String content){
        this.receiverLogin = otherUser;
        this.type = type;
        this.createdTime = new Date();
        this.content = content;
        this.senderLogin= "";
        this.senderNickname = "";

    }
    
    public Notification(Integer type, String content){
        this.content = content;
        this.type = type;
        this.createdTime = new Date();
        this.content = content;
        this.senderLogin= "";
        this.senderNickname = "";
    }


	public Notification(Map<String,String> map) throws Exception {
		if ( (map.get("createdTime").length()<1)
		|| (map.get("type").length()<1)
		|| (map.get("senderLogin").length()<1)
		|| (map.get("senderNickname").length()<1) ) {
			throw new Exception("ERR Necessary attribute is null is the map: "+map);
		}

		Integer aType = null;
		try {
			aType = new Integer((String)map.get("type"));
		} catch(NumberFormatException nfe) {
			throw new Exception("ERR number format exception for the type number in the map: "+map.get("type"));
		}

		Date aTime = new Date();
		try {
			aTime.setTime(new Long((String)map.get("createdTime")));
		} catch(NumberFormatException nfe) {
			throw new Exception("ERR number format exception for the timestamp number in the map: "+map.get("createdTime"));
		}

		this.setContent(map.get("content"));
		this.setCreatedTime(aTime);
		this.setReceiverLogin(map.get("receiverLogin"));
		this.setSenderLogin(map.get("senderLogin"));
		this.setSenderNickname(map.get("senderNickname"));
		this.setType(aType);
	}

	// <editor-fold defaultstate="collapsed" desc="Getters/Setters">
	public String getContent() {
		return content;
	}

	public void setContent(String content) {
		this.content = content;
	}

	public Date getCreatedTime() {
		return createdTime;
	}

	public void setCreatedTime(Date createdTime) {
		this.createdTime = createdTime;
	}

	public String getReceiverLogin() {
		return receiverLogin;
	}

	public void setReceiverLogin(String receiverLogin) {
		this.receiverLogin = receiverLogin;
	}

	public String getSenderLogin() {
		return senderLogin;
	}

	public void setSenderLogin(String senderLogin) {
		this.senderLogin = senderLogin;
	}

	public Integer getType() {
		return type;
	}

	public void setType(Integer type) {
		this.type = type;
	}

	public String getSenderNickname() {
		return senderNickname;
	}

	public void setSenderNickname(String senderNickname) {
		this.senderNickname = senderNickname;
	}
	// </editor-fold>

	public static Map<String,String> getEmptyAttributesMap() {
		Map<String,String> map = new Hashtable(6);

		map.put("createdTime", "");
		map.put("type", "");
		map.put("content", "");
		map.put("senderLogin", "");
		map.put("senderNickname", "");
		map.put("receiverLogin", "");

		return map;
	}

	public String getMessage() {
		switch (this.type) {
			case FRIENDSHIP_PROPOSAL: return this.senderNickname+" wants to become your friend";
			case FRIENDSHIP_ACCEPTED: return this.senderNickname+" accepted to be your friend";
			case FRIENDSHIP_DECLINED: return this.senderNickname+" declined your invitation to be his friend";
			case FRIENDSHIP_REMOVED: return this.senderNickname+" removed you from his friends";
			case NOTIFY_FILE: return this.senderNickname+" shared the file \""+this.content+"\"";

			case SENT_FRIENDSHIP_PROPOSAL: return "You proposed "+this.senderNickname+" to be his friend";
			case SENT_FRIENDSHIP_ACCEPTED: return "You accepted to be friend with "+this.senderNickname;
			case SENT_FRIENDSHIP_DECLINED: return "You refused to be friend with "+this.senderNickname;
			case SENT_FRIENDSHIP_REMOVED: return "You removed "+this.senderNickname+" from your friends";
			case SENT_NOTIFY_FILE_GROUP: return "You shared \""+this.getContent()+"\" with the group \""+this.getReceiverLogin()+"\"";
			case SENT_NOTIFY_FILE_FRIEND: return "You shared \""+this.getContent()+"\" with "+this.getReceiverLogin();

			case FILE_DOWNLOADING_STARTED : return "You started downloading \""+this.content +"\"";
			case FILE_DOWNLOAD_FINISHED : return "\""+this.content +"\" download is complete";
			case FILE_DOWNLOAD_ERROR : return "Error while trying to download \""+this.content +"\"";
			case LIST_FILE_DOWNLOADED : return "You downloaded a file list from "+this.content;
			case LIST_FILE_SENT : return this.content+" requested your file list";
    }
		return "";
	}

	public String getRelativeDate() {
		final int SECOND = 1;
		final int MINUTE = 60 * SECOND;
		final int HOUR = 60 * MINUTE;
		final int DAY = 24 * HOUR;
		final int MONTH = 30 * DAY;

		long delta = Math.round((new Date().getTime() - this.getCreatedTime().getTime())/1000);

		if (delta < 1 * MINUTE)
		{
			return delta <= 1 ? "one second ago" : delta + " seconds ago";
		}
		if (delta < 2 * MINUTE)
		{
			return "a minute ago";
		}
		if (delta < 45 * MINUTE)
		{
			return Math.round(delta/MINUTE) + " minutes ago";
		}
		if (delta < 90 * MINUTE)
		{
			return "an hour ago";
		}
		if (delta < 24 * HOUR)
		{
			return Math.round(delta/HOUR) + " hours ago";
		}
		if (delta < 48 * HOUR)
		{
			return "yesterday";
		}
		if (delta < 30 * DAY)
		{
			return Math.round(delta/DAY) + " days ago";
		}
		if (delta < 12 * MONTH)
		{
			long months = Math.round(delta/MONTH);
			return months <= 1 ? "one month ago" : months + " months ago";
		}
		else
		{
			long years = Math.round( Math.floor(delta/DAY) / 365);
			return years <= 1 ? "one year ago" : years + " years ago";
		}

	}

}
